import axios from "axios";
import { ElMessage } from "element-plus";
import { refreshToken } from "./index.js";
import router from "@/router/index.js";
import store from "@/store";

const service = axios.create({
  baseURL: import.meta.env.VITE_APP_BASE_API, //基础路径上会携带/api
  timeout: 60 * 1000,
});
// 是否正在刷新的标记
let isRefreshing = false;
//重试队列
let requests = [];

// Request interceptors
service.interceptors.request.use(
  (config) => {
    if (sessionStorage.getItem("token")) {
      config.headers.Authorization = sessionStorage.getItem("token");
    }
    return config;
  },
  (error) => {
    Promise.reject(error);
  }
);

// 处理token 过期
async function refreshTokenFunc(response) {
  if (!isRefreshing) {
    isRefreshing = true;
    //调用刷新token的接口
    refreshToken(store.state?.user?.UserInfo || {})
      .then((res) => {
        // 替换token
        if (res.data) {
          sessionStorage.setItem("token", `Bearer ${res.data.accessToken}`);
          sessionStorage.setItem("UserInfo", JSON.stringify(res.data));
          store.commit("user/setToken", `Bearer ${res.data.accessToken}`);
          store.commit("user/setUserInfo", res.data);
          response.headers.Authorization = `Bearer ${res.data.accessToken}`;
          requests.forEach((cb) => cb(`Bearer ${res.data.accessToken}`));
          requests = [];
          // return service(response.config);
        } else {
          ElMessage.error("登录凭证过期，请重新登陆"); //错误信息
          // window.location.href = "/";
          router.push("/login");
        }
      })
      .catch((err) => {
        // window.location.href = "/";
        router.push("/login");
        console.log(err);
      })
      .finally(() => {
        isRefreshing = false;
      });
  }
  return new Promise((resolve) => {
    // 将resolve放进队列，用一个函数形式来保存，等token刷新后直接执行
    requests.push((token) => {
      response.config.headers.Authorization = `Bearer ${token}`;
      resolve(service(response.config)); //执行请求，
    });
  });
}

// 特殊处理 blob 数据的401
async function blobRefreshTokenFunc(response) {
  return new Promise(async (resolve, reject) => {
    try {
      var blobReader = new Response(response.data).json();
      blobReader
        .then((res) => {
          if (res?.code === 401) {
            resolve(refreshTokenFunc(response));
          } else {
            ElMessage.error(res?.msg || "服务器忙，请稍后再试~"); //错误信息
            reject(response && response.data);
          }
        })
        .catch((res) => {
          // 真正的文件流
          resolve(response && response.data);
        });
    } catch (error) {
      // 真正的文件流
      resolve(response && response.data);
    }
  });
}

// Response interceptors
service.interceptors.response.use(
  async (response) => {
    if (
      response.data.code === 401 &&
      response.config.url.includes("/system/auth/refresh-token")
    ) {
      ElMessage({
        type: "error",
        message: response.data.msg || "登录凭证过期，请重新登陆",
      });
      router.push("/login");
    } else {
      if (response.config.responseType) {
        return await blobRefreshTokenFunc(response);
      } else {
        if (response.data.code === 401) {
          return await refreshTokenFunc(response);
        } else if (response.data?.code !== 0) {
          ElMessage({
            type: "error",
            message: response.data.msg || "服务器忙，请稍后再试~",
          });
        }
      }
    }
    return response && response.data;
  },
  (err) => {
    // 当响应异常时做一些处理
    if (err && err.response) {
      switch (err.response.status) {
        case 400:
          err.message = "请求错误(400)";
          break;
        case 401:
          err.message = "未授权，请重新登录(401)";
          break;
        case 403:
          err.message = "拒绝访问(403)";
          break;
        case 404:
          err.message = "请求出错(404)";
          break;
        case 408:
          err.message = "请求超时(408)";
          break;
        case 500:
          err.message = "服务器错误(500)";
          break;
        case 501:
          err.message = "服务未实现(501)";
          break;
        case 502:
          err.message = "网络错误(502)";
          break;
        case 503:
          err.message = "服务不可用(503)";
          break;
        case 504:
          err.message = "网络超时(504)";
          break;
        case 505:
          err.message = "HTTP版本不受支持(505)";
          break;
        default:
          err.message = `连接出错(${err.response.status})!`;
      }
    } else {
      err.message = "连接服务器失败!";
    }
    ElMessage({
      type: "error",
      message: err.message || "服务器忙,请稍后再试~",
    });
    return Promise.resolve(err);
  }
);

export default service;
